package com.tansun.easycare.rule.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.alibaba.druid.util.StringUtils;
import com.tansun.easycare.rule.common.BomCreator;
import com.tansun.easycare.rule.common.CommonEnum;
import com.tansun.easycare.rule.common.model.BaseItem;
import com.tansun.easycare.rule.common.model.Bom;
import com.tansun.easycare.rule.common.model.BomField;
import com.tansun.easycare.rule.common.model.Domain;
import com.tansun.easycare.rule.common.model.DomainItem;
import com.tansun.easycare.rule.common.service.impl.DataBomServiceImpl;
import com.tansun.easycare.rule.decisiontree.model.DecisionSubNode;
import com.tansun.easycare.rule.decisiontree.model.DecisionSubNodeItem;
import com.tansun.easycare.rule.policytree.model.PolicyTreeItem;
import com.tansun.easycare.rule.policytree.model.PolicyTreeKey;
import com.tansun.easycare.rule.policytree.model.PolicyTreeModel;
import com.tansun.easycare.rule.policytree.model.PolicyTreeScene;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.scoremodel.entity.RuleScoreInfo;
import com.tansun.easycare.rule.scoremodel.model.ScoreItem;
import com.tansun.easycare.rule.table.exclusions.entity.ExclusionsBO;

/**
 * 模型导出
 */
public class ExcelDownloadUtils {

    //决策树最大深度
    private int depth;
    //树节点映射集
    private Map<String, DecisionSubNode> nodeMap;
    //节点输出项列表
    //private List<DecisionTreeItem> treeItemList;
    private List<DecisionSubNode> leafNodes;
    //节点父ID->子节点列表
    private Map<String, List<DecisionSubNode>> childNodesMap;

    //导出文件
    private XSSFWorkbook workbook;
    // 中文参数名称Key
    private Map<String, BomField> paramZnMap = new HashMap<String, BomField>();
    // 英文文参数名称Key
    private Map<String, BomField> paramEnMap = new HashMap<String, BomField>();
    private Map<String, Domain> attrMap;
    //合并单元格样式
    private XSSFCellStyle mergedStyle;
    //标题样式
    private XSSFCellStyle titleStyle;
    
    private Map<String,String> keyMap = new HashMap<String,String>() {{
        put(">=", "[");
        put(">", "(");
        put("<=", "]");
        put("<", ")");
        put("==", "@");
        put("!=", "#");
    }};

    public ExcelDownloadUtils(Map<String, Domain> attrMap, Map<String, Bom> metaMap) {
        getParam(metaMap);
        this.attrMap = attrMap;
        this.workbook = new XSSFWorkbook();
        this.titleStyle = workbook.createCellStyle();
        this.titleStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        this.titleStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        // 设置字体
        XSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 20);
        font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        this.titleStyle.setFont(font);
    }

    // 设置默认单元格样式
    private void setMergedCenterStyle(boolean isCenter) {
        this.mergedStyle = workbook.createCellStyle();
        if (isCenter) {
            this.mergedStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
            this.mergedStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        } else {
            this.mergedStyle.setAlignment(XSSFCellStyle.ALIGN_LEFT);
            this.mergedStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_TOP);
        }
    }

    /**
     * 导出决策树
     */
    public Workbook downloadTree(RuleManage tree, List<DecisionSubNode> nodeList) throws Exception {
        this.initTree(nodeList);
        XSSFSheet sheet = workbook.createSheet();
        //1.写入标题
        this.createMergedCell(sheet, 0, 0, 0, 8, tree.getName()+"@@"+tree.getIsSingle());
        sheet.getRow(0).getCell(0).setCellStyle(this.titleStyle);
        //2.写入树节点信息
        int childCount = recursiveChileNode("0", sheet, 3, 0, 1);// 填充树形信息
        String rootStr = null;
        for (DecisionSubNode tmpNode : this.nodeMap.values()) {
            if (tmpNode.getPid() != null && tmpNode.getPid().equals("0")) {
                rootStr = tmpNode.getId();
            }
        }
        String val = this.formatNode(this.nodeMap.get(rootStr));
        this.createMergedCell(sheet, 3, 0, 3 + childCount - 1, 0, val);// 树根节点信息
        Row row = sheet.createRow(3 + childCount);
        row.createCell(0).setCellValue("{end}");
        //3.写入第二行及第三行表头
        this.createMergedCell(sheet, 1, 0, 1, this.depth - 1, "条件区");// 第二行：条件区
        row = sheet.getRow(1);
        row.createCell(this.depth).setCellValue("{#}");
        row = sheet.createRow(2);
        row.createCell(0).setCellValue("根节点");
        for (int i = 1; i < this.depth; i++) {
            row.createCell(i).setCellValue("子节点");
        }
        row.createCell(this.depth).setCellValue("{#}叶子节点");
        int j = this.depth + 1;
        DecisionSubNode subnode = null;
        for (DecisionSubNode node : nodeList) {
            if (org.apache.commons.lang3.StringUtils.isNotBlank(node.getIsLeaf()) && "true".equals(node.getIsLeaf())) {
                subnode = node;
            }
        }
        if (subnode.getResultItems() != null && subnode.getResultItems().size() > 0) {
            for (DecisionSubNodeItem e : subnode.getResultItems()) {
                row.createCell(j++).setCellValue(e.getNameCN());
            }
        } else {
            j++;
        }
        row.createCell(j).setCellValue("{#}");
        this.createMergedCell(sheet, 1, this.depth + 1, 1, j - 1, "输出变量");// 第二行：输出变量
        //4.写入节点结果信息
        for (int i = 0; i < leafNodes.size(); i++) {
            row = sheet.getRow(3 + i);
            if (row == null) continue;
            DecisionSubNode node = leafNodes.get(i);
            List<DecisionSubNodeItem> results = node.getResultItems();
            for (j = 0; j < results.size(); j++) {
                DecisionSubNodeItem e = results.get(j);

                if (!"true".equals(e.getDisabled())) {
                    val = parseControlVal(e, e.getControlValue());
                    row.createCell(this.depth + 1 + j).setCellValue(val);
                    if (j == 0) {
                        row.createCell(this.depth).setCellValue("{#}" + node.getName());
                    }
                }

            }
        }
        return workbook;
    }

    /**
     * 递归输出子节点信息
     *
     * @param pid      父节点ID
     * @param rowIndex 当前行
     * @param colIndex 当前列
     * @param curDepth 当前深度
     */
    private int recursiveChileNode(String pid, XSSFSheet sheet, int rowIndex, int colIndex, int curDepth) {

        List<DecisionSubNode> childNodes = this.childNodesMap.get(pid);
        Row row = sheet.getRow(rowIndex) == null ?
                sheet.createRow(rowIndex) : sheet.getRow(rowIndex);
        //无子节点，分支结束
        if (childNodes == null) {
            Cell cell = row.createCell(colIndex);
            cell.setCellValue("{#}");
            return 1;
        }
        int num = 0;
        for (int i = 0; i < childNodes.size(); i++) {
            DecisionSubNode node = childNodes.get(i);

            if ("true".equals(node.getIsLeaf())) {
                Cell cell = row.createCell(colIndex);
                cell.setCellValue("{#}");
                leafNodes.add(node);
                num++;
            } else {
                if (curDepth > this.depth) {
                    this.depth = curDepth;
                }
                int childCount = this.recursiveChileNode(node.getId(), sheet, rowIndex, colIndex + 1, curDepth + 1);
                String val = this.formatNode(node);
                this.createMergedCell(sheet, rowIndex, colIndex, rowIndex + childCount - 1, colIndex, val);
                rowIndex = rowIndex + childCount;
                num = num + childCount;
            }

        }
        return num;
    }

    /**
     * 初始化决策树信息
     */
    private void initTree(List<DecisionSubNode> nodeList) throws Exception {
        leafNodes = new ArrayList<DecisionSubNode>();
        this.nodeMap = new HashMap<String, DecisionSubNode>();
        this.childNodesMap = new HashMap<String, List<DecisionSubNode>>();
        for (DecisionSubNode node : nodeList) {
            nodeMap.put(node.getId(), node);
            //nodeMap.put(node.getName(), node);
            List<DecisionSubNode> childNodeList = this.childNodesMap.get(node.getPid());
            if (childNodeList == null) {
                childNodeList = new ArrayList<DecisionSubNode>();
                this.childNodesMap.put(node.getPid(), childNodeList);
            }
            childNodeList.add(node);
        }
    }

    /**
     * 导出排除项
     */
    @SuppressWarnings("unchecked")
    public Workbook downloadExclusion(RuleManage exclusionsModel, List<ExclusionsBO> exclusionsList) throws Exception {
        // 获取排除项
        XSSFWorkbook workbook = getCurrWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        // 写标题
        createMergedCell(sheet, 0, 0, 0, 8, exclusionsModel.getName());

        Row row = sheet.getRow(0);
        Cell cell = row.getCell(0);
        cell.setCellStyle(getTitleStyle());

        int index = 0;
        do {
            row = sheet.createRow(index + 1);

            // 读取执行2次第一个元素，用于表格头和第一行数据
            ExclusionsBO exsItem = exclusionsList.get(index == 0 ? index : index - 1);
            // 输出变量列表
            List<ExclusionsBO> outputList = exsItem.getList();

            // 写表格头
            if (index == 0) {
                // 空2个单元格
                row.createCell(0).setCellValue("/");
                row.createCell(1).setCellValue("/");

                for (int j = 0; j < outputList.size(); j++) {
                    ExclusionsBO outputItem = outputList.get(j);
                    // 输出变量名，从第3列开始
                    row.createCell(j + 2).setCellValue(outputItem.getNamecn());
                }
            } else {
                // 输入变量名和变量值
                row.createCell(0).setCellValue(exsItem.getNamecn());
                BaseItem b = new BaseItem(exsItem);
                String controlValue = exsItem.getControlValue();
                if (!StringUtils.isEmpty(exsItem.getLowerOpt()) && !StringUtils.isEmpty(exsItem.getUpperOpt())) {
                    controlValue = exsItem.getLowerOpt() + exsItem.getControlValue() + exsItem.getUpperOpt();
                }
                row.createCell(1).setCellValue(parseControlVal(b, controlValue));

                for (int k = 0; k < outputList.size(); k++) {
                    ExclusionsBO outputItem = outputList.get(k);
                    // 输出变量值
                    BaseItem x = new BaseItem(outputItem);
                    row.createCell(k + 2).setCellValue(parseControlVal(x, outputItem.getControlValue()));
                }
            }

            // 写行结束标识
            row.createCell(exsItem.getList().size() + 2).setCellValue("{#}");
        } while (index++ < exclusionsList.size());

        // 写结束标识
        sheet.createRow(index + 1).createCell(0).setCellValue("{end}");

        return workbook;
    }

    /**
     * 导出评分模型
     *
     * @param scoreModel 模型
     */
    public Workbook downloadScore(RuleManage scoreModel, List<ScoreItem> scoreItemList) throws Exception {
        //2.写入表格
        //写入首行标题
        XSSFSheet sheet = workbook.createSheet("分段细分");

        this.createMergedCell(sheet, 0, 0, 0, 8, scoreModel.getName());
        Row row = sheet.getRow(0);
        Cell cell = row.getCell(0);
        cell.setCellStyle(this.titleStyle);
        //表头行
        row = sheet.createRow(1);
        row.createCell(0).setCellValue("输入参数");
        row.createCell(1).setCellValue("变量系数");
        row.createCell(2).setCellValue("评分分段");
        row.createCell(3).setCellValue("分段描述");
        row.createCell(4).setCellValue("评分分数/线性公式");

        XSSFSheet sheet2 = workbook.createSheet("汇总衍生");
        this.createMergedCell(sheet2, 0, 0, 0, 3, "汇总计算公式");
        Row row_2 = sheet2.getRow(0);
        Cell cell_2 = row.getCell(0);
        cell_2.setCellStyle(this.titleStyle);
        //表头行
        row_2 = sheet2.createRow(1);
        row_2.createCell(0).setCellValue("输出参数");
        row_2.createCell(1).setCellValue("等于");
        row_2.createCell(2).setCellValue("汇总公式中文描述");
        //row_2.createCell(3).setCellValue("汇总公式(编码形式)");
        //HSSFSheet scoreSheet = workbook.createSheet("评分分段");
        //写入参数值
        int rowIndex = 2;//分段细分Sheet的行标
        int rowIndex2 = 2;//分段细分Sheet的行标
        for (ScoreItem scoreItem : scoreItemList) {
            row = sheet.createRow(rowIndex);
            //初始评分
            if ("InitialScore".equals(scoreItem.getClassName())) {
                row.createCell(0).setCellValue("初始评分");
                row.createCell(1).setCellValue(scoreItem.getScoreParam());
                rowIndex++;
                continue;
            }
        }
        for (int i = 0; i < scoreItemList.size(); i++) {
            ScoreItem item = scoreItemList.get(i);
            if (CommonEnum.ScoreModelType.scoreDetail.toString().equals(item.getContentType())) {
                row = sheet.createRow(rowIndex);
                //初始评分
                if ("InitialScore".equals(item.getClassName())) {
                    // row.createCell(0).setCellValue(item.getNamecn());
                    // row.createCell(1).setCellValue(item.getScoreParam());
                    // rowIndex++;
                    continue;
                }
                this.createMergedCell(sheet, rowIndex, 0, rowIndex + item.getList().size() - 1, 0, item.getNamecn());
                this.createMergedCell(sheet, rowIndex, 1, rowIndex + item.getList().size() - 1, 1, String.valueOf(item.getScoreParam()));
                for (int j = 0; j < item.getList().size(); j++) {
                    RuleScoreInfo child = item.getList().get(j);
                    String val = this.formatParam(item, child);
                    if (j > 0) {
                        row = sheet.createRow(rowIndex + j);
                    }
                    row.createCell(2).setCellValue(val);
                    row.createCell(3).setCellValue(child.getScopeDesc());
                    //0 为分段
                    if("0".equals(child.getSectionType())) {
                    	row.createCell(4).setCellValue(child.getScoreVal());
                    }else if("2".equals(child.getSectionType())) {
                    	// 2 为线性
                    	row.createCell(4).setCellValue(child.getFormulaLabel());
                    }else {
                    	// 默认为分段
                    	row.createCell(4).setCellValue(child.getScoreVal());
                    }
                    
                }
                rowIndex = rowIndex + item.getList().size();

            } else if (CommonEnum.ScoreModelType.scoreSection.toString().equals(item.getContentType())) {
            	row_2 = sheet2.createRow(rowIndex2);
            	row_2.createCell(0).setCellValue(item.getNamecn());
            	row_2.createCell(1).setCellValue("=");
            	row_2.createCell(2).setCellValue(item.getFormulaLabel());
            	//row_2.createCell(3).setCellValue(item.getFormula());
            	rowIndex2 = rowIndex2 + 1;
            } else if (CommonEnum.ScoreModelType.scoreSummary.toString().equals(item.getContentType())) {
            	row_2 = sheet2.createRow(rowIndex2);
            	row_2.createCell(0).setCellValue(item.getNamecn());
            	row_2.createCell(1).setCellValue("=");
            	row_2.createCell(2).setCellValue(item.getFormulaLabel());
            	//row_2.createCell(3).setCellValue(item.getFormula());
            	rowIndex2 = rowIndex2 + 1;
            }
        }
        sheet.createRow(rowIndex).createCell(0).setCellValue("{end}");

        return workbook;
    }


    /**
     * 转化评分模型参数输出格式
     */
    private String formatParam(ScoreItem item, RuleScoreInfo child) {
        if ("1".equals(child.getIsOther())) {
            return child.getLabel();
        }
        String val = "";


        if ("String".equals(item.getDataType())) {
            val = child.getLabel();
            /*if (child.getSymbol() != null) {
                //val = " " + child.getSymbol() + child.getContrastVals();
                val = " " + child.getSymbol() + "[\"" + child.getLabel() + "\"]";
            }*/
            if ("0".equals(child.getSymbol())) {
                /*if (StringUtils.isEmpty(item.getDomain())) {
                    return val = child.getLabel();
                } else {
                    val = "!" + val.substring(1, val.indexOf(")"));
                }*/
            	val += "!";

            }
        } else if ("Boolean".equals(item.getDataType())) {
            return "1".equals(child.getContrastVals()) ? "是" : "否";
        } else {
        	String lowerOpt = child.getLowerOpt();
            if (StringUtils.isEmpty(lowerOpt)) {
            	val += "(,";
                if (StringUtils.isEmpty(child.getUpperOpt())) {
                    return "";
                }
                val += child.getUpperVal();
                val += keyMap.get(child.getUpperOpt());
                return val;
            }
            if("==".equals(lowerOpt) || "!=".equals(lowerOpt)) {
                val += keyMap.get(lowerOpt);
                val += child.getLowerVal();
            }else {
                val += keyMap.get(lowerOpt);
                val += child.getLowerVal();
                val += ",";
                if (StringUtils.isEmpty(child.getUpperOpt())) {
                    val += ")";
                    return val;
                }
                val += child.getUpperVal();
                val += keyMap.get(child.getUpperOpt());
            }
        }
        return val;
    }
    
    /**
     * 格式化决策树节点输出内容
     *
     * @param node 节点id
     */
    private String formatNode(DecisionSubNode node) {
        StringBuilder str = new StringBuilder();

        str.append(node.getName());
        if (node.getNodeItems() == null || node.getNodeItems().size() == 0) {
            return str.toString();
        }
        str.append("{");
        for (DecisionSubNodeItem item : node.getNodeItems()) {
            String symbol = item.getSymbol();
            if ("0".equals(symbol)) {//不包含
                symbol = "not in";
            } else if ("1".equals(symbol)) {//包含
                symbol = "in";
            }
            String val = item.getControlValue();
            if (val.startsWith("[")) {
                val = val.substring(1, val.length() - 1);
                val = val.replace("\"", "");
                String[] vals = val.split(",");
                String result = "";
                Domain domain = getDomain(item.getDomain());
                for (DomainItem dom : domain.getDomainItems()) {
                    for (String v : vals) {
                        if (dom.getValue().equals(v)) {
                            result += dom.getLabel() + ",";
                            break;
                        }
                    }
                }
                result = result.substring(0, result.length() - 1);
                val = "(" + result + ")";
            }
            String leftOpt = StringUtils.isEmpty(item.getLeftOpt()) ? "" : item.getLeftOpt();
            String rightOpt = StringUtils.isEmpty(item.getRightOpt()) ? "" : item.getRightOpt();
            str.append(leftOpt).append(item.getNameCN()).append(" ").append(symbol).append(" ").
                    append(val).append(rightOpt);
        }
        str.append("}");
        return str.toString();
    }

    /**
     * 转化节点输出值
     */
    public String parseControlVal(BaseItem base, String controlVal) {
        if (base.getDataType().equals("String")) {
            if (!StringUtils.isEmpty(base.getDomain())) {
                Domain domain = getDomain(base.getDomain());
                if (controlVal.startsWith("[")) {
                    controlVal = controlVal.substring(1, controlVal.length() - 1);
                    controlVal = controlVal.replaceAll("\"", "");
                    String[] vals = controlVal.split(",");
                    StringBuilder result = new StringBuilder();
                    for (DomainItem item : domain.getDomainItems()) {
                        for (String str : vals) {
                            if (str.equals(item.getValue())) {
                                result.append(item.getLabel()).append(",");
                                break;
                            }
                        }
                    }
                    if (result.length() > 0) {
                        result.deleteCharAt(result.length() - 1);
                    }
                    return result.toString();
                } else {
                    for (DomainItem item : domain.getDomainItems()) {
                        if (item.getValue().equals(controlVal)) {
                            return item.getLabel();
                        }
                    }
                }
            }
        } else if (base.getDataType().equals("Date") || base.getDataType().equals("Double") || base.getDataType().equals("Long")) {
            controlVal = controlVal.replaceAll("@", "");
        }
        return controlVal;
    }

    /**
     * 导出策略树
     *
     * @param entity 树ID
     */
    public Workbook downloadPolicyTree(PolicyTreeModel entity) throws Exception {
        // 1、通过树ID获取策略树
        RuleManage policyTree = entity.getPolicyTreeModel();
        if (policyTree == null) {
            throw new IllegalStateException("策略树信息不存在");
        }
        // 2、策略树页签
        XSSFSheet sheet = workbook.createSheet("策略树");
        // --2.1、写入标题
        this.createMergedCell(sheet, 0, 0, 0, 8, policyTree.getName());
        Row row = sheet.getRow(0);
        row.getCell(0).setCellStyle(this.titleStyle);

        // --2.2、写决策键
        List<PolicyTreeKey> keys = entity.getPolicyTreeKey();
        // 决策键Map<id,Key Object>
        Map<String, PolicyTreeKey> keyMap = new HashMap<String, PolicyTreeKey>();
        for (int i = 0; i < keys.size(); i++) {
            PolicyTreeKey key = keys.get(i);
            row = sheet.createRow(key.getFloor() + 1);
            row.createCell(0).setCellValue(key.getName());
            keyMap.put(key.getId(), key);
        }
        sheet.createRow(keys.size() + 2).createCell(0).setCellValue("{end}");
        // 2.3、写入策略树
        List<PolicyTreeItem> items = entity.getPolicyTreeItem();
        PolicyTreeItem root = new PolicyTreeItem(); // 根节点
        Map<String, List<PolicyTreeItem>> pMc = new HashMap<String, List<PolicyTreeItem>>(); // 父节点与子节点对应关系{parent,children}
        for (PolicyTreeItem node : items) {
            if ("ROOT_V".equals(node.getId())) {
                root = node;
            }
            String pid = node.getPid();
            List<PolicyTreeItem> children = pMc.get(pid);
            if (children == null) {
                children = new ArrayList<PolicyTreeItem>();
                pMc.put(pid, children);
            }
            children.add(node);
        }

        setMergedCenterStyle(false);// 合并单元格默认居左
        // 动作场景Map<id, Scene Object>
        List<PolicyTreeScene> scenes = entity.getActionScene();
        HashMap<String, PolicyTreeScene> sceneMap = new HashMap<String, PolicyTreeScene>();
        for (int i = 0; i < scenes.size(); i++) {
            PolicyTreeScene scene = scenes.get(i);
            sceneMap.put(scene.getId(), scene);
        }
        createPolicyTree(sheet, root, pMc, 1, keyMap, sceneMap);// 输出树形
//		this.createMergedCell(sheet, 1, 1, 1, 1+childCount-1, root.getName());// 树根节点信息
        // 3、动作场景页签
        createActionScene(policyTree.getName(), scenes);

        return workbook;
    }

    /**
     * 写动作场景
     */
    private void createActionScene(String treeName, List<PolicyTreeScene> scenes) {
        XSSFSheet sheet2 = workbook.createSheet("动作场景");
        this.createMergedCell(sheet2, 0, 0, 0, 8, treeName);
        Row row2 = sheet2.getRow(0);
        row2.getCell(0).setCellStyle(this.titleStyle);

        int header = 0;//为0表示未写入过表头行
        for (int i = 0; i < scenes.size(); i++) {
            PolicyTreeScene scene = scenes.get(i);
            // 写入表头参数名称信息
            row2 = sheet2.createRow(i + 1 + header);
            row2.createCell(0).setCellValue(i + header == 0 ? scene.getLabel() :
                    this.parseControlVal(scene, scene.getControlValue()));
            for (int j = 0; j < scene.getOutputVariables().size(); j++) {
                PolicyTreeScene e = scene.getOutputVariables().get(j);
                row2.createCell(j + 1).setCellValue(i + header == 0 ? e.getLabel() :
                        this.parseControlVal(e, e.getControlValue()));
            }
            row2.createCell(scene.getOutputVariables().size() + 1).setCellValue("{#}");
            if (i + header == 0) {
                header = 1;
                i--;
            }
        }
        sheet2.createRow(scenes.size() + 2).createCell(0).setCellValue("{end}");
    }

    /**
     * 创建策略树
     *
     * @param p        父节点
     * @param colIndex 当前列
     * @param keyMap   决策键map
     * @param sceneMap 动作场景map
     */
    private int createPolicyTree(Sheet sheet, PolicyTreeItem p,
                                 Map<String, List<PolicyTreeItem>> pMc, int colIndex,
                                 Map<String, PolicyTreeKey> keyMap, Map<String, PolicyTreeScene> sceneMap) {
        int floor = p.getFloor() + 1;// 层，即行
        List<PolicyTreeItem> children = pMc.get(p.getId());
        Row row = sheet.getRow(floor) == null ?
                sheet.createRow(floor) : sheet.getRow(floor);
        int size = children == null ? 0 : children.size();
        if (size == 0) {// 叶子
            row.createCell(colIndex).setCellValue(formatPolicyTreeItem(p, keyMap, sceneMap));
            row.createCell(colIndex + 1).setCellValue("{#}");
            return 1;
        } else {// 分支
            int num = 0;
            // 不合并单元格模式
            row.createCell(colIndex).setCellValue(formatPolicyTreeItem(p, keyMap, sceneMap));
//			row.createCell(colIndex+1).setCellValue("{#}");
            for (int i = 0; i < children.size(); i++) {
                PolicyTreeItem c = children.get(i);
                num += createPolicyTree(sheet, c, pMc, colIndex + num, keyMap, sceneMap);
            }
            // 合并单元格模式
            this.createMergedCell(sheet, floor, colIndex, floor, colIndex + num - 1, row.getCell(colIndex).toString());
            return num;
        }
    }

    // 格式化item
    private String formatPolicyTreeItem(PolicyTreeItem item, Map<String, PolicyTreeKey> keyMap, Map<String, PolicyTreeScene> sceneMap) {
        StringBuilder str = new StringBuilder();
        if ("ROOT_V".equals(item.getId())) {// 根节点
            str.append(item.getName());
        } else {
            if ("true".equals(item.getIsLeaf())) {// 叶子节点 例如：性别
                PolicyTreeScene scene = sceneMap.get(item.getActionSceneId());
//				str.append(convertDomain(scene.getDomain(), scene.getControlValue()));
                str.append(parseControlVal(scene, scene.getControlValue()));
            } else {// 分支
                PolicyTreeKey key = keyMap.get(item.getKeyId());
                String dataType = key.getDataType();
                if ("Date".equals(dataType) || "Long".equals(dataType) || "Double".equals(dataType)) {// 例如：征信最大预期期次
                    String val = "";
                    String[] controlValus = item.getControlValue().split(",");
                    if (!StringUtils.isEmpty(item.getLeftOpt()) && controlValus.length == 2 && !StringUtils.isEmpty(item.getRightOpt())) {
                        val = " " + item.getLeftOpt() + " " + controlValus[0] + " && " + item.getRightOpt() + " " + controlValus[1];
                    } else if (!StringUtils.isEmpty(item.getLeftOpt())) {
                        val = " " + item.getLeftOpt() + " " + controlValus[0];
                    } else if (!StringUtils.isEmpty(item.getRightOpt())) {
                        val = " " + item.getRightOpt() + " " + controlValus[0];
                    }
                    str.append("{" + val + "}");
                } else if ("String".equals(dataType) && !StringUtils.isEmpty(key.getDomain())) {// 例如：学历
                    String symbol = item.getSymbol().equals("0") ? " not in " : " in ";
                    String result = "";
                    for (String control : item.getControlValue().split(",")) {
                        result += parseControlVal(key, control) + ",";
                    }
                    str.append("{" + symbol + "(" + result.substring(0, result.length() - 1) + ")" + "}");
                } else {// 例如：家庭电话
                    str.append("{" + item.getSymbol() + item.getControlValue() + "}");
                }
            }
        }
        return str.toString();
    }

    /**
     * 创建合并单元格
     *
     * @param sheet    表格
     * @param firstRow 首行
     * @param firstCol 首列
     * @param lastRow  最后一行
     * @param lastCol  最后一列
     */
    public void createMergedCell(Sheet sheet, int firstRow, int firstCol, int lastRow, int lastCol, String val) {
        if (firstRow < lastRow || firstCol < lastCol) {
            CellRangeAddress cra = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            // 在sheet里增加合并单元格
            sheet.addMergedRegion(cra);
        }
        Row row = sheet.getRow(firstRow);
        if (row == null)
            row = sheet.createRow(firstRow);
        Cell cell = row.createCell(firstCol);
        if (this.mergedStyle == null) {
            setMergedCenterStyle(true);
        }
        cell.setCellStyle(this.mergedStyle);
        cell.setCellValue(val);
    }

    /***根据数据模型的domain值获取数据模型属性***/
    public Domain getDomain(String key) {
        Domain domain = null;
        if (attrMap.containsKey(key))
            domain = attrMap.get(key);
        return domain;
    }

    private void getParam(Map<String, Bom> metaMap) {
        List<Bom> list = BomCreator.findTopObject(metaMap);
        if (list == null || list.size() == 0)
            return;
        for (Bom item : list) {
            if (item.getBomFields() == null || item.getBomFields().size() == 0)
                continue;
            for (BomField field : item.getBomFields()) {
                field.setClassName(item.getName());
                this.paramZnMap.put(field.getLabel(), field);
                this.paramEnMap.put(field.getName(), field);
            }
        }
        BomField initial = new BomField();
        initial.setClassName("InitialScore");
        initial.setLabel("初始评分");
        initial.setName("initialScore");
        initial.setDataType("Double");
        this.paramZnMap.put("初始评分", initial);
    }

    private void getAttribute(String projectCode) {
        attrMap = new DataBomServiceImpl().findDomainByProjectCode(projectCode);
    }

    public XSSFWorkbook getCurrWorkbook() {
        return this.workbook;
    }

    public XSSFCellStyle getTitleStyle() {
        return this.titleStyle;
    }
}
